namespace ZFramework
{
    public struct Rgba32
    {
        public enum Format
        {
            RGBA,
            ARGB,
            ABGR,
        }
        public uint Rgba { get; private set; }
        public Rgba32(uint code, Format format = Format.RGBA)
        {
            switch (format)
            {
                case Format.RGBA:
                    Rgba = code;
                    break;

                case Format.ARGB:
                    {
                        var a = code & 0xff000000;
                        Rgba = (code << 8) | (a >> 24);
                        break;
                    }

                case Format.ABGR:
                    {
                        var a = code & 0xff000000;
                        var b = code & 0xff0000;
                        var g = code & 0xff00;
                        Rgba = (code << 24) | (g << 8) | (b >> 8) | (a >> 24);
                        break;
                    }
            }
        }

        public Rgba32(byte r, byte g, byte b, byte a)
        {
            Rgba = (uint)(r << 24 + g << 16 + b << 8 + a);
        }

        public byte R
        {
            readonly get => (byte)(Rgba >> 24);
            set => Rgba = (Rgba & 0xffffff) + (uint)(value << 24);
        }
        public byte G
        {
            readonly get => (byte)(Rgba >> 16);
            set => Rgba = (Rgba & 0xff00ffff) + (uint)(value << 16);
        }
        public byte B
        {
            readonly get => (byte)(Rgba >> 8);
            set => Rgba = (Rgba & 0xffff00ff) + (uint)(value << 8);
        }
        public byte A
        {
            readonly get => (byte)Rgba;
            set => Rgba = (Rgba & 0xffffff00) + value;
        }

        public static implicit operator uint(Rgba32 color) => color.Rgba;
        public static implicit operator Rgba32(uint color) => new(color);

#if GODOT4
        public static implicit operator Godot.Color(Rgba32 color) => new(color.Rgba);
        public static implicit operator Rgba32(Godot.Color color) => new(color.ToRgba32());
#endif

        public static Rgba32 White => new() { Rgba = 0xffffffff };
        public static Rgba32 Black => new() { Rgba = 0xff };
        public static Rgba32 Red => new() { Rgba = 0xff0000ff };
        public static Rgba32 Green => new() { Rgba = 0xff00ff };
        public static Rgba32 Blue => new() { Rgba = 0xffff };
        public static Rgba32 Orange => new() { Rgba = 0xff8000ff };
        public static Rgba32 Yellow => new() { Rgba = 0xffff00ff };
        public static Rgba32 Cyan => new() { Rgba = 0xffffff };
        public static Rgba32 Magenta => new() { Rgba = 0xff00ffff };
    }
}